home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / python2.6 / compiler / pycodegen.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-11-11  |  55KB  |  1,705 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import imp
  5. import os
  6. import marshal
  7. import struct
  8. import sys
  9. from cStringIO import StringIO
  10. from compiler import ast, parse, walk, syntax
  11. from compiler import pyassem, misc, future, symbols
  12. from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
  13. from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION, CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION
  14. from compiler.pyassem import TupleArg
  15.  
  16. try:
  17.     VERSION = sys.version_info[0]
  18. except AttributeError:
  19.     VERSION = 1
  20.  
  21. callfunc_opcode_info = {
  22.     (0, 0): 'CALL_FUNCTION',
  23.     (1, 0): 'CALL_FUNCTION_VAR',
  24.     (0, 1): 'CALL_FUNCTION_KW',
  25.     (1, 1): 'CALL_FUNCTION_VAR_KW' }
  26. LOOP = 1
  27. EXCEPT = 2
  28. TRY_FINALLY = 3
  29. END_FINALLY = 4
  30.  
  31. def compileFile(filename, display = 0):
  32.     f = open(filename, 'U')
  33.     buf = f.read()
  34.     f.close()
  35.     mod = Module(buf, filename)
  36.     
  37.     try:
  38.         mod.compile(display)
  39.     except SyntaxError:
  40.         raise 
  41.  
  42.     f = open(filename + 'c', 'wb')
  43.     mod.dump(f)
  44.     f.close()
  45.  
  46.  
  47. def compile(source, filename, mode, flags = None, dont_inherit = None):
  48.     '''Replacement for builtin compile() function'''
  49.     if flags is not None or dont_inherit is not None:
  50.         raise RuntimeError, 'not implemented yet'
  51.     dont_inherit is not None
  52.     if mode == 'single':
  53.         gen = Interactive(source, filename)
  54.     elif mode == 'exec':
  55.         gen = Module(source, filename)
  56.     elif mode == 'eval':
  57.         gen = Expression(source, filename)
  58.     else:
  59.         raise ValueError("compile() 3rd arg must be 'exec' or 'eval' or 'single'")
  60.     (mode == 'single').compile()
  61.     return gen.code
  62.  
  63.  
  64. class AbstractCompileMode:
  65.     mode = None
  66.     
  67.     def __init__(self, source, filename):
  68.         self.source = source
  69.         self.filename = filename
  70.         self.code = None
  71.  
  72.     
  73.     def _get_tree(self):
  74.         tree = parse(self.source, self.mode)
  75.         misc.set_filename(self.filename, tree)
  76.         syntax.check(tree)
  77.         return tree
  78.  
  79.     
  80.     def compile(self):
  81.         pass
  82.  
  83.     
  84.     def getCode(self):
  85.         return self.code
  86.  
  87.  
  88.  
  89. class Expression(AbstractCompileMode):
  90.     mode = 'eval'
  91.     
  92.     def compile(self):
  93.         tree = self._get_tree()
  94.         gen = ExpressionCodeGenerator(tree)
  95.         self.code = gen.getCode()
  96.  
  97.  
  98.  
  99. class Interactive(AbstractCompileMode):
  100.     mode = 'single'
  101.     
  102.     def compile(self):
  103.         tree = self._get_tree()
  104.         gen = InteractiveCodeGenerator(tree)
  105.         self.code = gen.getCode()
  106.  
  107.  
  108.  
  109. class Module(AbstractCompileMode):
  110.     mode = 'exec'
  111.     
  112.     def compile(self, display = 0):
  113.         tree = self._get_tree()
  114.         gen = ModuleCodeGenerator(tree)
  115.         if display:
  116.             import pprint as pprint
  117.             print pprint.pprint(tree)
  118.         
  119.         self.code = gen.getCode()
  120.  
  121.     
  122.     def dump(self, f):
  123.         f.write(self.getPycHeader())
  124.         marshal.dump(self.code, f)
  125.  
  126.     MAGIC = imp.get_magic()
  127.     
  128.     def getPycHeader(self):
  129.         mtime = os.path.getmtime(self.filename)
  130.         mtime = struct.pack('<i', mtime)
  131.         return self.MAGIC + mtime
  132.  
  133.  
  134.  
  135. class LocalNameFinder:
  136.     '''Find local names in scope'''
  137.     
  138.     def __init__(self, names = ()):
  139.         self.names = misc.Set()
  140.         self.globals = misc.Set()
  141.         for name in names:
  142.             self.names.add(name)
  143.         
  144.  
  145.     
  146.     def getLocals(self):
  147.         for elt in self.globals.elements():
  148.             if self.names.has_elt(elt):
  149.                 self.names.remove(elt)
  150.                 continue
  151.         
  152.         return self.names
  153.  
  154.     
  155.     def visitDict(self, node):
  156.         pass
  157.  
  158.     
  159.     def visitGlobal(self, node):
  160.         for name in node.names:
  161.             self.globals.add(name)
  162.         
  163.  
  164.     
  165.     def visitFunction(self, node):
  166.         self.names.add(node.name)
  167.  
  168.     
  169.     def visitLambda(self, node):
  170.         pass
  171.  
  172.     
  173.     def visitImport(self, node):
  174.         for name, alias in node.names:
  175.             if not alias:
  176.                 pass
  177.             self.names.add(name)
  178.         
  179.  
  180.     
  181.     def visitFrom(self, node):
  182.         for name, alias in node.names:
  183.             if not alias:
  184.                 pass
  185.             self.names.add(name)
  186.         
  187.  
  188.     
  189.     def visitClass(self, node):
  190.         self.names.add(node.name)
  191.  
  192.     
  193.     def visitAssName(self, node):
  194.         self.names.add(node.name)
  195.  
  196.  
  197.  
  198. def is_constant_false(node):
  199.     if isinstance(node, ast.Const):
  200.         if not node.value:
  201.             return 1
  202.     
  203.     return 0
  204.  
  205.  
  206. class CodeGenerator:
  207.     '''Defines basic code generator for Python bytecode
  208.  
  209.     This class is an abstract base class.  Concrete subclasses must
  210.     define an __init__() that defines self.graph and then calls the
  211.     __init__() defined in this class.
  212.  
  213.     The concrete class must also define the class attributes
  214.     NameFinder, FunctionGen, and ClassGen.  These attributes can be
  215.     defined in the initClass() method, which is a hook for
  216.     initializing these methods after all the classes have been
  217.     defined.
  218.     '''
  219.     optimized = 0
  220.     __initialized = None
  221.     class_name = None
  222.     
  223.     def __init__(self):
  224.         if self._CodeGenerator__initialized is None:
  225.             self.initClass()
  226.             self.__class__._CodeGenerator__initialized = 1
  227.         
  228.         self.checkClass()
  229.         self.locals = misc.Stack()
  230.         self.setups = misc.Stack()
  231.         self.last_lineno = None
  232.         self._setupGraphDelegation()
  233.         self._div_op = 'BINARY_DIVIDE'
  234.         futures = self.get_module().futures
  235.         for feature in futures:
  236.             if feature == 'division':
  237.                 self.graph.setFlag(CO_FUTURE_DIVISION)
  238.                 self._div_op = 'BINARY_TRUE_DIVIDE'
  239.                 continue
  240.             if feature == 'absolute_import':
  241.                 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
  242.                 continue
  243.             if feature == 'with_statement':
  244.                 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
  245.                 continue
  246.             if feature == 'print_function':
  247.                 self.graph.setFlag(CO_FUTURE_PRINT_FUNCTION)
  248.                 continue
  249.         
  250.  
  251.     
  252.     def initClass(self):
  253.         '''This method is called once for each class'''
  254.         pass
  255.  
  256.     
  257.     def checkClass(self):
  258.         '''Verify that class is constructed correctly'''
  259.         
  260.         try:
  261.             if not hasattr(self, 'graph'):
  262.                 raise AssertionError
  263.             if not getattr(self, 'NameFinder'):
  264.                 raise AssertionError
  265.             if not getattr(self, 'FunctionGen'):
  266.                 raise AssertionError
  267.             if not getattr(self, 'ClassGen'):
  268.                 raise AssertionError
  269.         except AssertionError:
  270.             msg = None
  271.             intro = 'Bad class construction for %s' % self.__class__.__name__
  272.             raise AssertionError, intro
  273.  
  274.  
  275.     
  276.     def _setupGraphDelegation(self):
  277.         self.emit = self.graph.emit
  278.         self.newBlock = self.graph.newBlock
  279.         self.startBlock = self.graph.startBlock
  280.         self.nextBlock = self.graph.nextBlock
  281.         self.setDocstring = self.graph.setDocstring
  282.  
  283.     
  284.     def getCode(self):
  285.         '''Return a code object'''
  286.         return self.graph.getCode()
  287.  
  288.     
  289.     def mangle(self, name):
  290.         if self.class_name is not None:
  291.             return misc.mangle(name, self.class_name)
  292.         return name
  293.  
  294.     
  295.     def parseSymbols(self, tree):
  296.         s = symbols.SymbolVisitor()
  297.         walk(tree, s)
  298.         return s.scopes
  299.  
  300.     
  301.     def get_module(self):
  302.         raise RuntimeError, 'should be implemented by subclasses'
  303.  
  304.     
  305.     def isLocalName(self, name):
  306.         return self.locals.top().has_elt(name)
  307.  
  308.     
  309.     def storeName(self, name):
  310.         self._nameOp('STORE', name)
  311.  
  312.     
  313.     def loadName(self, name):
  314.         self._nameOp('LOAD', name)
  315.  
  316.     
  317.     def delName(self, name):
  318.         self._nameOp('DELETE', name)
  319.  
  320.     
  321.     def _nameOp(self, prefix, name):
  322.         name = self.mangle(name)
  323.         scope = self.scope.check_name(name)
  324.         if scope == SC_LOCAL:
  325.             if not self.optimized:
  326.                 self.emit(prefix + '_NAME', name)
  327.             else:
  328.                 self.emit(prefix + '_FAST', name)
  329.         elif scope == SC_GLOBAL:
  330.             if not self.optimized:
  331.                 self.emit(prefix + '_NAME', name)
  332.             else:
  333.                 self.emit(prefix + '_GLOBAL', name)
  334.         elif scope == SC_FREE or scope == SC_CELL:
  335.             self.emit(prefix + '_DEREF', name)
  336.         else:
  337.             raise RuntimeError, 'unsupported scope for var %s: %d' % (name, scope)
  338.         return scope == SC_CELL
  339.  
  340.     
  341.     def _implicitNameOp(self, prefix, name):
  342.         """Emit name ops for names generated implicitly by for loops
  343.  
  344.         The interpreter generates names that start with a period or
  345.         dollar sign.  The symbol table ignores these names because
  346.         they aren't present in the program text.
  347.         """
  348.         if self.optimized:
  349.             self.emit(prefix + '_FAST', name)
  350.         else:
  351.             self.emit(prefix + '_NAME', name)
  352.  
  353.     
  354.     def set_lineno(self, node, force = False):
  355.         '''Emit SET_LINENO if necessary.
  356.  
  357.         The instruction is considered necessary if the node has a
  358.         lineno attribute and it is different than the last lineno
  359.         emitted.
  360.  
  361.         Returns true if SET_LINENO was emitted.
  362.  
  363.         There are no rules for when an AST node should have a lineno
  364.         attribute.  The transformer and AST code need to be reviewed
  365.         and a consistent policy implemented and documented.  Until
  366.         then, this method works around missing line numbers.
  367.         '''
  368.         lineno = getattr(node, 'lineno', None)
  369.         if lineno is not None:
  370.             if lineno != self.last_lineno or force:
  371.                 self.emit('SET_LINENO', lineno)
  372.                 self.last_lineno = lineno
  373.                 return True
  374.             return False
  375.  
  376.     NameFinder = LocalNameFinder
  377.     FunctionGen = None
  378.     ClassGen = None
  379.     
  380.     def visitModule(self, node):
  381.         self.scopes = self.parseSymbols(node)
  382.         self.scope = self.scopes[node]
  383.         self.emit('SET_LINENO', 0)
  384.         if node.doc:
  385.             self.emit('LOAD_CONST', node.doc)
  386.             self.storeName('__doc__')
  387.         
  388.         lnf = walk(node.node, self.NameFinder(), verbose = 0)
  389.         self.locals.push(lnf.getLocals())
  390.         self.visit(node.node)
  391.         self.emit('LOAD_CONST', None)
  392.         self.emit('RETURN_VALUE')
  393.  
  394.     
  395.     def visitExpression(self, node):
  396.         self.set_lineno(node)
  397.         self.scopes = self.parseSymbols(node)
  398.         self.scope = self.scopes[node]
  399.         self.visit(node.node)
  400.         self.emit('RETURN_VALUE')
  401.  
  402.     
  403.     def visitFunction(self, node):
  404.         self._visitFuncOrLambda(node, isLambda = 0)
  405.         if node.doc:
  406.             self.setDocstring(node.doc)
  407.         
  408.         self.storeName(node.name)
  409.  
  410.     
  411.     def visitLambda(self, node):
  412.         self._visitFuncOrLambda(node, isLambda = 1)
  413.  
  414.     
  415.     def _visitFuncOrLambda(self, node, isLambda = 0):
  416.         if not isLambda and node.decorators:
  417.             for decorator in node.decorators.nodes:
  418.                 self.visit(decorator)
  419.             
  420.             ndecorators = len(node.decorators.nodes)
  421.         else:
  422.             ndecorators = 0
  423.         gen = self.FunctionGen(node, self.scopes, isLambda, self.class_name, self.get_module())
  424.         walk(node.code, gen)
  425.         gen.finish()
  426.         self.set_lineno(node)
  427.         for default in node.defaults:
  428.             self.visit(default)
  429.         
  430.         self._makeClosure(gen, len(node.defaults))
  431.         for i in range(ndecorators):
  432.             self.emit('CALL_FUNCTION', 1)
  433.         
  434.  
  435.     
  436.     def visitClass(self, node):
  437.         gen = self.ClassGen(node, self.scopes, self.get_module())
  438.         walk(node.code, gen)
  439.         gen.finish()
  440.         self.set_lineno(node)
  441.         self.emit('LOAD_CONST', node.name)
  442.         for base in node.bases:
  443.             self.visit(base)
  444.         
  445.         self.emit('BUILD_TUPLE', len(node.bases))
  446.         self._makeClosure(gen, 0)
  447.         self.emit('CALL_FUNCTION', 0)
  448.         self.emit('BUILD_CLASS')
  449.         self.storeName(node.name)
  450.  
  451.     
  452.     def visitIf(self, node):
  453.         end = self.newBlock()
  454.         numtests = len(node.tests)
  455.         for i in range(numtests):
  456.             (test, suite) = node.tests[i]
  457.             if is_constant_false(test):
  458.                 continue
  459.             
  460.             self.set_lineno(test)
  461.             self.visit(test)
  462.             nextTest = self.newBlock()
  463.             self.emit('JUMP_IF_FALSE', nextTest)
  464.             self.nextBlock()
  465.             self.emit('POP_TOP')
  466.             self.visit(suite)
  467.             self.emit('JUMP_FORWARD', end)
  468.             self.startBlock(nextTest)
  469.             self.emit('POP_TOP')
  470.         
  471.         if node.else_:
  472.             self.visit(node.else_)
  473.         
  474.         self.nextBlock(end)
  475.  
  476.     
  477.     def visitWhile(self, node):
  478.         self.set_lineno(node)
  479.         loop = self.newBlock()
  480.         else_ = self.newBlock()
  481.         after = self.newBlock()
  482.         self.emit('SETUP_LOOP', after)
  483.         self.nextBlock(loop)
  484.         self.setups.push((LOOP, loop))
  485.         self.set_lineno(node, force = True)
  486.         self.visit(node.test)
  487.         if not else_:
  488.             pass
  489.         self.emit('JUMP_IF_FALSE', after)
  490.         self.nextBlock()
  491.         self.emit('POP_TOP')
  492.         self.visit(node.body)
  493.         self.emit('JUMP_ABSOLUTE', loop)
  494.         self.startBlock(else_)
  495.         self.emit('POP_TOP')
  496.         self.emit('POP_BLOCK')
  497.         self.setups.pop()
  498.         if node.else_:
  499.             self.visit(node.else_)
  500.         
  501.         self.nextBlock(after)
  502.  
  503.     
  504.     def visitFor(self, node):
  505.         start = self.newBlock()
  506.         anchor = self.newBlock()
  507.         after = self.newBlock()
  508.         self.setups.push((LOOP, start))
  509.         self.set_lineno(node)
  510.         self.emit('SETUP_LOOP', after)
  511.         self.visit(node.list)
  512.         self.emit('GET_ITER')
  513.         self.nextBlock(start)
  514.         self.set_lineno(node, force = 1)
  515.         self.emit('FOR_ITER', anchor)
  516.         self.visit(node.assign)
  517.         self.visit(node.body)
  518.         self.emit('JUMP_ABSOLUTE', start)
  519.         self.nextBlock(anchor)
  520.         self.emit('POP_BLOCK')
  521.         self.setups.pop()
  522.         if node.else_:
  523.             self.visit(node.else_)
  524.         
  525.         self.nextBlock(after)
  526.  
  527.     
  528.     def visitBreak(self, node):
  529.         if not self.setups:
  530.             raise SyntaxError, "'break' outside loop (%s, %d)" % (node.filename, node.lineno)
  531.         self.setups
  532.         self.set_lineno(node)
  533.         self.emit('BREAK_LOOP')
  534.  
  535.     
  536.     def visitContinue(self, node):
  537.         if not self.setups:
  538.             raise SyntaxError, "'continue' outside loop (%s, %d)" % (node.filename, node.lineno)
  539.         self.setups
  540.         (kind, block) = self.setups.top()
  541.         if kind == LOOP:
  542.             self.set_lineno(node)
  543.             self.emit('JUMP_ABSOLUTE', block)
  544.             self.nextBlock()
  545.         elif kind == EXCEPT or kind == TRY_FINALLY:
  546.             self.set_lineno(node)
  547.             top = len(self.setups)
  548.             while top > 0:
  549.                 top = top - 1
  550.                 (kind, loop_block) = self.setups[top]
  551.                 if kind == LOOP:
  552.                     break
  553.                     continue
  554.             if kind != LOOP:
  555.                 raise SyntaxError, "'continue' outside loop (%s, %d)" % (node.filename, node.lineno)
  556.             kind != LOOP
  557.             self.emit('CONTINUE_LOOP', loop_block)
  558.             self.nextBlock()
  559.         elif kind == END_FINALLY:
  560.             msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
  561.             raise SyntaxError, msg % (node.filename, node.lineno)
  562.         
  563.  
  564.     
  565.     def visitTest(self, node, jump):
  566.         end = self.newBlock()
  567.         for child in node.nodes[:-1]:
  568.             self.visit(child)
  569.             self.emit(jump, end)
  570.             self.nextBlock()
  571.             self.emit('POP_TOP')
  572.         
  573.         self.visit(node.nodes[-1])
  574.         self.nextBlock(end)
  575.  
  576.     
  577.     def visitAnd(self, node):
  578.         self.visitTest(node, 'JUMP_IF_FALSE')
  579.  
  580.     
  581.     def visitOr(self, node):
  582.         self.visitTest(node, 'JUMP_IF_TRUE')
  583.  
  584.     
  585.     def visitIfExp(self, node):
  586.         endblock = self.newBlock()
  587.         elseblock = self.newBlock()
  588.         self.visit(node.test)
  589.         self.emit('JUMP_IF_FALSE', elseblock)
  590.         self.emit('POP_TOP')
  591.         self.visit(node.then)
  592.         self.emit('JUMP_FORWARD', endblock)
  593.         self.nextBlock(elseblock)
  594.         self.emit('POP_TOP')
  595.         self.visit(node.else_)
  596.         self.nextBlock(endblock)
  597.  
  598.     
  599.     def visitCompare(self, node):
  600.         self.visit(node.expr)
  601.         cleanup = self.newBlock()
  602.         for op, code in node.ops[:-1]:
  603.             self.visit(code)
  604.             self.emit('DUP_TOP')
  605.             self.emit('ROT_THREE')
  606.             self.emit('COMPARE_OP', op)
  607.             self.emit('JUMP_IF_FALSE', cleanup)
  608.             self.nextBlock()
  609.             self.emit('POP_TOP')
  610.         
  611.         if node.ops:
  612.             (op, code) = node.ops[-1]
  613.             self.visit(code)
  614.             self.emit('COMPARE_OP', op)
  615.         
  616.         if len(node.ops) > 1:
  617.             end = self.newBlock()
  618.             self.emit('JUMP_FORWARD', end)
  619.             self.startBlock(cleanup)
  620.             self.emit('ROT_TWO')
  621.             self.emit('POP_TOP')
  622.             self.nextBlock(end)
  623.         
  624.  
  625.     __list_count = 0
  626.     
  627.     def visitListComp(self, node):
  628.         self.set_lineno(node)
  629.         tmpname = '$list%d' % self._CodeGenerator__list_count
  630.         self._CodeGenerator__list_count = self._CodeGenerator__list_count + 1
  631.         self.emit('BUILD_LIST', 0)
  632.         self.emit('DUP_TOP')
  633.         self._implicitNameOp('STORE', tmpname)
  634.         stack = []
  635.         for i, for_ in zip(range(len(node.quals)), node.quals):
  636.             (start, anchor) = self.visit(for_)
  637.             cont = None
  638.             for if_ in for_.ifs:
  639.                 if cont is None:
  640.                     cont = self.newBlock()
  641.                 
  642.                 self.visit(if_, cont)
  643.             
  644.             stack.insert(0, (start, cont, anchor))
  645.         
  646.         self._implicitNameOp('LOAD', tmpname)
  647.         self.visit(node.expr)
  648.         self.emit('LIST_APPEND')
  649.         for start, cont, anchor in stack:
  650.             if cont:
  651.                 skip_one = self.newBlock()
  652.                 self.emit('JUMP_FORWARD', skip_one)
  653.                 self.startBlock(cont)
  654.                 self.emit('POP_TOP')
  655.                 self.nextBlock(skip_one)
  656.             
  657.             self.emit('JUMP_ABSOLUTE', start)
  658.             self.startBlock(anchor)
  659.         
  660.         self._implicitNameOp('DELETE', tmpname)
  661.         self._CodeGenerator__list_count = self._CodeGenerator__list_count - 1
  662.  
  663.     
  664.     def visitListCompFor(self, node):
  665.         start = self.newBlock()
  666.         anchor = self.newBlock()
  667.         self.visit(node.list)
  668.         self.emit('GET_ITER')
  669.         self.nextBlock(start)
  670.         self.set_lineno(node, force = True)
  671.         self.emit('FOR_ITER', anchor)
  672.         self.nextBlock()
  673.         self.visit(node.assign)
  674.         return (start, anchor)
  675.  
  676.     
  677.     def visitListCompIf(self, node, branch):
  678.         self.set_lineno(node, force = True)
  679.         self.visit(node.test)
  680.         self.emit('JUMP_IF_FALSE', branch)
  681.         self.newBlock()
  682.         self.emit('POP_TOP')
  683.  
  684.     
  685.     def _makeClosure(self, gen, args):
  686.         frees = gen.scope.get_free_vars()
  687.         if frees:
  688.             for name in frees:
  689.                 self.emit('LOAD_CLOSURE', name)
  690.             
  691.             self.emit('BUILD_TUPLE', len(frees))
  692.             self.emit('LOAD_CONST', gen)
  693.             self.emit('MAKE_CLOSURE', args)
  694.         else:
  695.             self.emit('LOAD_CONST', gen)
  696.             self.emit('MAKE_FUNCTION', args)
  697.  
  698.     
  699.     def visitGenExpr(self, node):
  700.         gen = GenExprCodeGenerator(node, self.scopes, self.class_name, self.get_module())
  701.         walk(node.code, gen)
  702.         gen.finish()
  703.         self.set_lineno(node)
  704.         self._makeClosure(gen, 0)
  705.         self.visit(node.code.quals[0].iter)
  706.         self.emit('GET_ITER')
  707.         self.emit('CALL_FUNCTION', 1)
  708.  
  709.     
  710.     def visitGenExprInner(self, node):
  711.         self.set_lineno(node)
  712.         stack = []
  713.         for i, for_ in zip(range(len(node.quals)), node.quals):
  714.             (start, anchor, end) = self.visit(for_)
  715.             cont = None
  716.             for if_ in for_.ifs:
  717.                 if cont is None:
  718.                     cont = self.newBlock()
  719.                 
  720.                 self.visit(if_, cont)
  721.             
  722.             stack.insert(0, (start, cont, anchor, end))
  723.         
  724.         self.visit(node.expr)
  725.         self.emit('YIELD_VALUE')
  726.         self.emit('POP_TOP')
  727.         for start, cont, anchor, end in stack:
  728.             if cont:
  729.                 skip_one = self.newBlock()
  730.                 self.emit('JUMP_FORWARD', skip_one)
  731.                 self.startBlock(cont)
  732.                 self.emit('POP_TOP')
  733.                 self.nextBlock(skip_one)
  734.             
  735.             self.emit('JUMP_ABSOLUTE', start)
  736.             self.startBlock(anchor)
  737.             self.emit('POP_BLOCK')
  738.             self.setups.pop()
  739.             self.startBlock(end)
  740.         
  741.         self.emit('LOAD_CONST', None)
  742.  
  743.     
  744.     def visitGenExprFor(self, node):
  745.         start = self.newBlock()
  746.         anchor = self.newBlock()
  747.         end = self.newBlock()
  748.         self.setups.push((LOOP, start))
  749.         self.emit('SETUP_LOOP', end)
  750.         if node.is_outmost:
  751.             self.loadName('.0')
  752.         else:
  753.             self.visit(node.iter)
  754.             self.emit('GET_ITER')
  755.         self.nextBlock(start)
  756.         self.set_lineno(node, force = True)
  757.         self.emit('FOR_ITER', anchor)
  758.         self.nextBlock()
  759.         self.visit(node.assign)
  760.         return (start, anchor, end)
  761.  
  762.     
  763.     def visitGenExprIf(self, node, branch):
  764.         self.set_lineno(node, force = True)
  765.         self.visit(node.test)
  766.         self.emit('JUMP_IF_FALSE', branch)
  767.         self.newBlock()
  768.         self.emit('POP_TOP')
  769.  
  770.     
  771.     def visitAssert(self, node):
  772.         end = self.newBlock()
  773.         self.set_lineno(node)
  774.         self.nextBlock()
  775.         self.visit(node.test)
  776.         self.emit('JUMP_IF_TRUE', end)
  777.         self.nextBlock()
  778.         self.emit('POP_TOP')
  779.         self.emit('LOAD_GLOBAL', 'AssertionError')
  780.         if node.fail:
  781.             self.visit(node.fail)
  782.             self.emit('RAISE_VARARGS', 2)
  783.         else:
  784.             self.emit('RAISE_VARARGS', 1)
  785.         self.nextBlock(end)
  786.         self.emit('POP_TOP')
  787.  
  788.     
  789.     def visitRaise(self, node):
  790.         self.set_lineno(node)
  791.         n = 0
  792.         if node.expr1:
  793.             self.visit(node.expr1)
  794.             n = n + 1
  795.         
  796.         if node.expr2:
  797.             self.visit(node.expr2)
  798.             n = n + 1
  799.         
  800.         if node.expr3:
  801.             self.visit(node.expr3)
  802.             n = n + 1
  803.         
  804.         self.emit('RAISE_VARARGS', n)
  805.  
  806.     
  807.     def visitTryExcept(self, node):
  808.         body = self.newBlock()
  809.         handlers = self.newBlock()
  810.         end = self.newBlock()
  811.         if node.else_:
  812.             lElse = self.newBlock()
  813.         else:
  814.             lElse = end
  815.         self.set_lineno(node)
  816.         self.emit('SETUP_EXCEPT', handlers)
  817.         self.nextBlock(body)
  818.         self.setups.push((EXCEPT, body))
  819.         self.visit(node.body)
  820.         self.emit('POP_BLOCK')
  821.         self.setups.pop()
  822.         self.emit('JUMP_FORWARD', lElse)
  823.         self.startBlock(handlers)
  824.         last = len(node.handlers) - 1
  825.         for i in range(len(node.handlers)):
  826.             (expr, target, body) = node.handlers[i]
  827.             self.set_lineno(expr)
  828.             if expr:
  829.                 self.emit('DUP_TOP')
  830.                 self.visit(expr)
  831.                 self.emit('COMPARE_OP', 'exception match')
  832.                 next = self.newBlock()
  833.                 self.emit('JUMP_IF_FALSE', next)
  834.                 self.nextBlock()
  835.                 self.emit('POP_TOP')
  836.             
  837.             self.emit('POP_TOP')
  838.             if target:
  839.                 self.visit(target)
  840.             else:
  841.                 self.emit('POP_TOP')
  842.             self.emit('POP_TOP')
  843.             self.visit(body)
  844.             self.emit('JUMP_FORWARD', end)
  845.             if expr:
  846.                 self.nextBlock(next)
  847.             else:
  848.                 self.nextBlock()
  849.             if expr:
  850.                 self.emit('POP_TOP')
  851.                 continue
  852.         
  853.         self.emit('END_FINALLY')
  854.         if node.else_:
  855.             self.nextBlock(lElse)
  856.             self.visit(node.else_)
  857.         
  858.         self.nextBlock(end)
  859.  
  860.     
  861.     def visitTryFinally(self, node):
  862.         body = self.newBlock()
  863.         final = self.newBlock()
  864.         self.set_lineno(node)
  865.         self.emit('SETUP_FINALLY', final)
  866.         self.nextBlock(body)
  867.         self.setups.push((TRY_FINALLY, body))
  868.         self.visit(node.body)
  869.         self.emit('POP_BLOCK')
  870.         self.setups.pop()
  871.         self.emit('LOAD_CONST', None)
  872.         self.nextBlock(final)
  873.         self.setups.push((END_FINALLY, final))
  874.         self.visit(node.final)
  875.         self.emit('END_FINALLY')
  876.         self.setups.pop()
  877.  
  878.     __with_count = 0
  879.     
  880.     def visitWith(self, node):
  881.         body = self.newBlock()
  882.         final = self.newBlock()
  883.         valuevar = '$value%d' % self._CodeGenerator__with_count
  884.         self._CodeGenerator__with_count += 1
  885.         self.set_lineno(node)
  886.         self.visit(node.expr)
  887.         self.emit('DUP_TOP')
  888.         self.emit('LOAD_ATTR', '__exit__')
  889.         self.emit('ROT_TWO')
  890.         self.emit('LOAD_ATTR', '__enter__')
  891.         self.emit('CALL_FUNCTION', 0)
  892.         if node.vars is None:
  893.             self.emit('POP_TOP')
  894.         else:
  895.             self._implicitNameOp('STORE', valuevar)
  896.         self.emit('SETUP_FINALLY', final)
  897.         self.nextBlock(body)
  898.         self.setups.push((TRY_FINALLY, body))
  899.         if node.vars is not None:
  900.             self._implicitNameOp('LOAD', valuevar)
  901.             self._implicitNameOp('DELETE', valuevar)
  902.             self.visit(node.vars)
  903.         
  904.         self.visit(node.body)
  905.         self.emit('POP_BLOCK')
  906.         self.setups.pop()
  907.         self.emit('LOAD_CONST', None)
  908.         self.nextBlock(final)
  909.         self.setups.push((END_FINALLY, final))
  910.         self.emit('WITH_CLEANUP')
  911.         self.emit('END_FINALLY')
  912.         self.setups.pop()
  913.         self._CodeGenerator__with_count -= 1
  914.  
  915.     
  916.     def visitDiscard(self, node):
  917.         self.set_lineno(node)
  918.         self.visit(node.expr)
  919.         self.emit('POP_TOP')
  920.  
  921.     
  922.     def visitConst(self, node):
  923.         self.emit('LOAD_CONST', node.value)
  924.  
  925.     
  926.     def visitKeyword(self, node):
  927.         self.emit('LOAD_CONST', node.name)
  928.         self.visit(node.expr)
  929.  
  930.     
  931.     def visitGlobal(self, node):
  932.         pass
  933.  
  934.     
  935.     def visitName(self, node):
  936.         self.set_lineno(node)
  937.         self.loadName(node.name)
  938.  
  939.     
  940.     def visitPass(self, node):
  941.         self.set_lineno(node)
  942.  
  943.     
  944.     def visitImport(self, node):
  945.         self.set_lineno(node)
  946.         level = None if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
  947.         for name, alias in node.names:
  948.             if VERSION > 1:
  949.                 self.emit('LOAD_CONST', level)
  950.                 self.emit('LOAD_CONST', None)
  951.             
  952.             self.emit('IMPORT_NAME', name)
  953.             mod = name.split('.')[0]
  954.             if alias:
  955.                 self._resolveDots(name)
  956.                 self.storeName(alias)
  957.                 continue
  958.             self.storeName(mod)
  959.         
  960.  
  961.     
  962.     def visitFrom(self, node):
  963.         self.set_lineno(node)
  964.         level = node.level
  965.         if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
  966.             level = -1
  967.         
  968.         fromlist = map((lambda .0: (name, alias) = .0name), node.names)
  969.         if VERSION > 1:
  970.             self.emit('LOAD_CONST', level)
  971.             self.emit('LOAD_CONST', tuple(fromlist))
  972.         
  973.         self.emit('IMPORT_NAME', node.modname)
  974.         for name, alias in node.names:
  975.             if VERSION > 1:
  976.                 if name == '*':
  977.                     self.namespace = 0
  978.                     self.emit('IMPORT_STAR')
  979.                     if not len(node.names) == 1:
  980.                         raise AssertionError
  981.                     return None
  982.                 self.emit('IMPORT_FROM', name)
  983.                 self._resolveDots(name)
  984.                 if not alias:
  985.                     pass
  986.                 self.storeName(name)
  987.                 continue
  988.             name == '*'
  989.             self.emit('IMPORT_FROM', name)
  990.         
  991.         self.emit('POP_TOP')
  992.  
  993.     
  994.     def _resolveDots(self, name):
  995.         elts = name.split('.')
  996.         if len(elts) == 1:
  997.             return None
  998.         for elt in elts[1:]:
  999.             self.emit('LOAD_ATTR', elt)
  1000.         
  1001.  
  1002.     
  1003.     def visitGetattr(self, node):
  1004.         self.visit(node.expr)
  1005.         self.emit('LOAD_ATTR', self.mangle(node.attrname))
  1006.  
  1007.     
  1008.     def visitAssign(self, node):
  1009.         self.set_lineno(node)
  1010.         self.visit(node.expr)
  1011.         dups = len(node.nodes) - 1
  1012.         for i in range(len(node.nodes)):
  1013.             elt = node.nodes[i]
  1014.             if i < dups:
  1015.                 self.emit('DUP_TOP')
  1016.             
  1017.             if isinstance(elt, ast.Node):
  1018.                 self.visit(elt)
  1019.                 continue
  1020.         
  1021.  
  1022.     
  1023.     def visitAssName(self, node):
  1024.         if node.flags == 'OP_ASSIGN':
  1025.             self.storeName(node.name)
  1026.         elif node.flags == 'OP_DELETE':
  1027.             self.set_lineno(node)
  1028.             self.delName(node.name)
  1029.         else:
  1030.             print 'oops', node.flags
  1031.  
  1032.     
  1033.     def visitAssAttr(self, node):
  1034.         self.visit(node.expr)
  1035.         if node.flags == 'OP_ASSIGN':
  1036.             self.emit('STORE_ATTR', self.mangle(node.attrname))
  1037.         elif node.flags == 'OP_DELETE':
  1038.             self.emit('DELETE_ATTR', self.mangle(node.attrname))
  1039.         else:
  1040.             print 'warning: unexpected flags:', node.flags
  1041.             print node
  1042.  
  1043.     
  1044.     def _visitAssSequence(self, node, op = 'UNPACK_SEQUENCE'):
  1045.         if findOp(node) != 'OP_DELETE':
  1046.             self.emit(op, len(node.nodes))
  1047.         
  1048.         for child in node.nodes:
  1049.             self.visit(child)
  1050.         
  1051.  
  1052.     if VERSION > 1:
  1053.         visitAssTuple = _visitAssSequence
  1054.         visitAssList = _visitAssSequence
  1055.     else:
  1056.         
  1057.         def visitAssTuple(self, node):
  1058.             self._visitAssSequence(node, 'UNPACK_TUPLE')
  1059.  
  1060.         
  1061.         def visitAssList(self, node):
  1062.             self._visitAssSequence(node, 'UNPACK_LIST')
  1063.  
  1064.     
  1065.     def visitAugAssign(self, node):
  1066.         self.set_lineno(node)
  1067.         aug_node = wrap_aug(node.node)
  1068.         self.visit(aug_node, 'load')
  1069.         self.visit(node.expr)
  1070.         self.emit(self._augmented_opcode[node.op])
  1071.         self.visit(aug_node, 'store')
  1072.  
  1073.     _augmented_opcode = {
  1074.         '+=': 'INPLACE_ADD',
  1075.         '-=': 'INPLACE_SUBTRACT',
  1076.         '*=': 'INPLACE_MULTIPLY',
  1077.         '/=': 'INPLACE_DIVIDE',
  1078.         '//=': 'INPLACE_FLOOR_DIVIDE',
  1079.         '%=': 'INPLACE_MODULO',
  1080.         '**=': 'INPLACE_POWER',
  1081.         '>>=': 'INPLACE_RSHIFT',
  1082.         '<<=': 'INPLACE_LSHIFT',
  1083.         '&=': 'INPLACE_AND',
  1084.         '^=': 'INPLACE_XOR',
  1085.         '|=': 'INPLACE_OR' }
  1086.     
  1087.     def visitAugName(self, node, mode):
  1088.         if mode == 'load':
  1089.             self.loadName(node.name)
  1090.         elif mode == 'store':
  1091.             self.storeName(node.name)
  1092.         
  1093.  
  1094.     
  1095.     def visitAugGetattr(self, node, mode):
  1096.         if mode == 'load':
  1097.             self.visit(node.expr)
  1098.             self.emit('DUP_TOP')
  1099.             self.emit('LOAD_ATTR', self.mangle(node.attrname))
  1100.         elif mode == 'store':
  1101.             self.emit('ROT_TWO')
  1102.             self.emit('STORE_ATTR', self.mangle(node.attrname))
  1103.         
  1104.  
  1105.     
  1106.     def visitAugSlice(self, node, mode):
  1107.         if mode == 'load':
  1108.             self.visitSlice(node, 1)
  1109.         elif mode == 'store':
  1110.             slice = 0
  1111.             if node.lower:
  1112.                 slice = slice | 1
  1113.             
  1114.             if node.upper:
  1115.                 slice = slice | 2
  1116.             
  1117.             if slice == 0:
  1118.                 self.emit('ROT_TWO')
  1119.             elif slice == 3:
  1120.                 self.emit('ROT_FOUR')
  1121.             else:
  1122.                 self.emit('ROT_THREE')
  1123.             self.emit('STORE_SLICE+%d' % slice)
  1124.         
  1125.  
  1126.     
  1127.     def visitAugSubscript(self, node, mode):
  1128.         if mode == 'load':
  1129.             self.visitSubscript(node, 1)
  1130.         elif mode == 'store':
  1131.             self.emit('ROT_THREE')
  1132.             self.emit('STORE_SUBSCR')
  1133.         
  1134.  
  1135.     
  1136.     def visitExec(self, node):
  1137.         self.visit(node.expr)
  1138.         if node.locals is None:
  1139.             self.emit('LOAD_CONST', None)
  1140.         else:
  1141.             self.visit(node.locals)
  1142.         if node.globals is None:
  1143.             self.emit('DUP_TOP')
  1144.         else:
  1145.             self.visit(node.globals)
  1146.         self.emit('EXEC_STMT')
  1147.  
  1148.     
  1149.     def visitCallFunc(self, node):
  1150.         pos = 0
  1151.         kw = 0
  1152.         self.set_lineno(node)
  1153.         self.visit(node.node)
  1154.         for arg in node.args:
  1155.             self.visit(arg)
  1156.             if isinstance(arg, ast.Keyword):
  1157.                 kw = kw + 1
  1158.                 continue
  1159.             pos = pos + 1
  1160.         
  1161.         if node.star_args is not None:
  1162.             self.visit(node.star_args)
  1163.         
  1164.         if node.dstar_args is not None:
  1165.             self.visit(node.dstar_args)
  1166.         
  1167.         have_star = node.star_args is not None
  1168.         have_dstar = node.dstar_args is not None
  1169.         opcode = callfunc_opcode_info[(have_star, have_dstar)]
  1170.         self.emit(opcode, kw << 8 | pos)
  1171.  
  1172.     
  1173.     def visitPrint(self, node, newline = 0):
  1174.         self.set_lineno(node)
  1175.         if node.dest:
  1176.             self.visit(node.dest)
  1177.         
  1178.         for child in node.nodes:
  1179.             if node.dest:
  1180.                 self.emit('DUP_TOP')
  1181.             
  1182.             self.visit(child)
  1183.             if node.dest:
  1184.                 self.emit('ROT_TWO')
  1185.                 self.emit('PRINT_ITEM_TO')
  1186.                 continue
  1187.             self.emit('PRINT_ITEM')
  1188.         
  1189.         if node.dest and not newline:
  1190.             self.emit('POP_TOP')
  1191.         
  1192.  
  1193.     
  1194.     def visitPrintnl(self, node):
  1195.         self.visitPrint(node, newline = 1)
  1196.         if node.dest:
  1197.             self.emit('PRINT_NEWLINE_TO')
  1198.         else:
  1199.             self.emit('PRINT_NEWLINE')
  1200.  
  1201.     
  1202.     def visitReturn(self, node):
  1203.         self.set_lineno(node)
  1204.         self.visit(node.value)
  1205.         self.emit('RETURN_VALUE')
  1206.  
  1207.     
  1208.     def visitYield(self, node):
  1209.         self.set_lineno(node)
  1210.         self.visit(node.value)
  1211.         self.emit('YIELD_VALUE')
  1212.  
  1213.     
  1214.     def visitSlice(self, node, aug_flag = None):
  1215.         self.visit(node.expr)
  1216.         slice = 0
  1217.         if node.lower:
  1218.             self.visit(node.lower)
  1219.             slice = slice | 1
  1220.         
  1221.         if node.upper:
  1222.             self.visit(node.upper)
  1223.             slice = slice | 2
  1224.         
  1225.         if aug_flag:
  1226.             if slice == 0:
  1227.                 self.emit('DUP_TOP')
  1228.             elif slice == 3:
  1229.                 self.emit('DUP_TOPX', 3)
  1230.             else:
  1231.                 self.emit('DUP_TOPX', 2)
  1232.         
  1233.         if node.flags == 'OP_APPLY':
  1234.             self.emit('SLICE+%d' % slice)
  1235.         elif node.flags == 'OP_ASSIGN':
  1236.             self.emit('STORE_SLICE+%d' % slice)
  1237.         elif node.flags == 'OP_DELETE':
  1238.             self.emit('DELETE_SLICE+%d' % slice)
  1239.         else:
  1240.             print 'weird slice', node.flags
  1241.             raise 
  1242.         return node.flags == 'OP_APPLY'
  1243.  
  1244.     
  1245.     def visitSubscript(self, node, aug_flag = None):
  1246.         self.visit(node.expr)
  1247.         for sub in node.subs:
  1248.             self.visit(sub)
  1249.         
  1250.         if len(node.subs) > 1:
  1251.             self.emit('BUILD_TUPLE', len(node.subs))
  1252.         
  1253.         if aug_flag:
  1254.             self.emit('DUP_TOPX', 2)
  1255.         
  1256.         if node.flags == 'OP_APPLY':
  1257.             self.emit('BINARY_SUBSCR')
  1258.         elif node.flags == 'OP_ASSIGN':
  1259.             self.emit('STORE_SUBSCR')
  1260.         elif node.flags == 'OP_DELETE':
  1261.             self.emit('DELETE_SUBSCR')
  1262.         
  1263.  
  1264.     
  1265.     def binaryOp(self, node, op):
  1266.         self.visit(node.left)
  1267.         self.visit(node.right)
  1268.         self.emit(op)
  1269.  
  1270.     
  1271.     def visitAdd(self, node):
  1272.         return self.binaryOp(node, 'BINARY_ADD')
  1273.  
  1274.     
  1275.     def visitSub(self, node):
  1276.         return self.binaryOp(node, 'BINARY_SUBTRACT')
  1277.  
  1278.     
  1279.     def visitMul(self, node):
  1280.         return self.binaryOp(node, 'BINARY_MULTIPLY')
  1281.  
  1282.     
  1283.     def visitDiv(self, node):
  1284.         return self.binaryOp(node, self._div_op)
  1285.  
  1286.     
  1287.     def visitFloorDiv(self, node):
  1288.         return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
  1289.  
  1290.     
  1291.     def visitMod(self, node):
  1292.         return self.binaryOp(node, 'BINARY_MODULO')
  1293.  
  1294.     
  1295.     def visitPower(self, node):
  1296.         return self.binaryOp(node, 'BINARY_POWER')
  1297.  
  1298.     
  1299.     def visitLeftShift(self, node):
  1300.         return self.binaryOp(node, 'BINARY_LSHIFT')
  1301.  
  1302.     
  1303.     def visitRightShift(self, node):
  1304.         return self.binaryOp(node, 'BINARY_RSHIFT')
  1305.  
  1306.     
  1307.     def unaryOp(self, node, op):
  1308.         self.visit(node.expr)
  1309.         self.emit(op)
  1310.  
  1311.     
  1312.     def visitInvert(self, node):
  1313.         return self.unaryOp(node, 'UNARY_INVERT')
  1314.  
  1315.     
  1316.     def visitUnarySub(self, node):
  1317.         return self.unaryOp(node, 'UNARY_NEGATIVE')
  1318.  
  1319.     
  1320.     def visitUnaryAdd(self, node):
  1321.         return self.unaryOp(node, 'UNARY_POSITIVE')
  1322.  
  1323.     
  1324.     def visitUnaryInvert(self, node):
  1325.         return self.unaryOp(node, 'UNARY_INVERT')
  1326.  
  1327.     
  1328.     def visitNot(self, node):
  1329.         return self.unaryOp(node, 'UNARY_NOT')
  1330.  
  1331.     
  1332.     def visitBackquote(self, node):
  1333.         return self.unaryOp(node, 'UNARY_CONVERT')
  1334.  
  1335.     
  1336.     def bitOp(self, nodes, op):
  1337.         self.visit(nodes[0])
  1338.         for node in nodes[1:]:
  1339.             self.visit(node)
  1340.             self.emit(op)
  1341.         
  1342.  
  1343.     
  1344.     def visitBitand(self, node):
  1345.         return self.bitOp(node.nodes, 'BINARY_AND')
  1346.  
  1347.     
  1348.     def visitBitor(self, node):
  1349.         return self.bitOp(node.nodes, 'BINARY_OR')
  1350.  
  1351.     
  1352.     def visitBitxor(self, node):
  1353.         return self.bitOp(node.nodes, 'BINARY_XOR')
  1354.  
  1355.     
  1356.     def visitEllipsis(self, node):
  1357.         self.emit('LOAD_CONST', Ellipsis)
  1358.  
  1359.     
  1360.     def visitTuple(self, node):
  1361.         self.set_lineno(node)
  1362.         for elt in node.nodes:
  1363.             self.visit(elt)
  1364.         
  1365.         self.emit('BUILD_TUPLE', len(node.nodes))
  1366.  
  1367.     
  1368.     def visitList(self, node):
  1369.         self.set_lineno(node)
  1370.         for elt in node.nodes:
  1371.             self.visit(elt)
  1372.         
  1373.         self.emit('BUILD_LIST', len(node.nodes))
  1374.  
  1375.     
  1376.     def visitSliceobj(self, node):
  1377.         for child in node.nodes:
  1378.             self.visit(child)
  1379.         
  1380.         self.emit('BUILD_SLICE', len(node.nodes))
  1381.  
  1382.     
  1383.     def visitDict(self, node):
  1384.         self.set_lineno(node)
  1385.         self.emit('BUILD_MAP', 0)
  1386.         for k, v in node.items:
  1387.             self.emit('DUP_TOP')
  1388.             self.visit(k)
  1389.             self.visit(v)
  1390.             self.emit('ROT_THREE')
  1391.             self.emit('STORE_SUBSCR')
  1392.         
  1393.  
  1394.  
  1395.  
  1396. class NestedScopeMixin:
  1397.     '''Defines initClass() for nested scoping (Python 2.2-compatible)'''
  1398.     
  1399.     def initClass(self):
  1400.         self.__class__.NameFinder = LocalNameFinder
  1401.         self.__class__.FunctionGen = FunctionCodeGenerator
  1402.         self.__class__.ClassGen = ClassCodeGenerator
  1403.  
  1404.  
  1405.  
  1406. class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
  1407.     __super_init = CodeGenerator.__init__
  1408.     scopes = None
  1409.     
  1410.     def __init__(self, tree):
  1411.         self.graph = pyassem.PyFlowGraph('<module>', tree.filename)
  1412.         self.futures = future.find_futures(tree)
  1413.         self._ModuleCodeGenerator__super_init()
  1414.         walk(tree, self)
  1415.  
  1416.     
  1417.     def get_module(self):
  1418.         return self
  1419.  
  1420.  
  1421.  
  1422. class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
  1423.     __super_init = CodeGenerator.__init__
  1424.     scopes = None
  1425.     futures = ()
  1426.     
  1427.     def __init__(self, tree):
  1428.         self.graph = pyassem.PyFlowGraph('<expression>', tree.filename)
  1429.         self._ExpressionCodeGenerator__super_init()
  1430.         walk(tree, self)
  1431.  
  1432.     
  1433.     def get_module(self):
  1434.         return self
  1435.  
  1436.  
  1437.  
  1438. class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
  1439.     __super_init = CodeGenerator.__init__
  1440.     scopes = None
  1441.     futures = ()
  1442.     
  1443.     def __init__(self, tree):
  1444.         self.graph = pyassem.PyFlowGraph('<interactive>', tree.filename)
  1445.         self._InteractiveCodeGenerator__super_init()
  1446.         self.set_lineno(tree)
  1447.         walk(tree, self)
  1448.         self.emit('RETURN_VALUE')
  1449.  
  1450.     
  1451.     def get_module(self):
  1452.         return self
  1453.  
  1454.     
  1455.     def visitDiscard(self, node):
  1456.         self.visit(node.expr)
  1457.         self.emit('PRINT_EXPR')
  1458.  
  1459.  
  1460.  
  1461. class AbstractFunctionCode:
  1462.     optimized = 1
  1463.     lambdaCount = 0
  1464.     
  1465.     def __init__(self, func, scopes, isLambda, class_name, mod):
  1466.         self.class_name = class_name
  1467.         self.module = mod
  1468.         if isLambda:
  1469.             klass = FunctionCodeGenerator
  1470.             name = '<lambda.%d>' % klass.lambdaCount
  1471.             klass.lambdaCount = klass.lambdaCount + 1
  1472.         else:
  1473.             name = func.name
  1474.         (args, hasTupleArg) = generateArgList(func.argnames)
  1475.         self.graph = pyassem.PyFlowGraph(name, func.filename, args, optimized = 1)
  1476.         self.isLambda = isLambda
  1477.         self.super_init()
  1478.         if not isLambda and func.doc:
  1479.             self.setDocstring(func.doc)
  1480.         
  1481.         lnf = walk(func.code, self.NameFinder(args), verbose = 0)
  1482.         self.locals.push(lnf.getLocals())
  1483.         if func.varargs:
  1484.             self.graph.setFlag(CO_VARARGS)
  1485.         
  1486.         if func.kwargs:
  1487.             self.graph.setFlag(CO_VARKEYWORDS)
  1488.         
  1489.         self.set_lineno(func)
  1490.         if hasTupleArg:
  1491.             self.generateArgUnpack(func.argnames)
  1492.         
  1493.  
  1494.     
  1495.     def get_module(self):
  1496.         return self.module
  1497.  
  1498.     
  1499.     def finish(self):
  1500.         self.graph.startExitBlock()
  1501.         if not self.isLambda:
  1502.             self.emit('LOAD_CONST', None)
  1503.         
  1504.         self.emit('RETURN_VALUE')
  1505.  
  1506.     
  1507.     def generateArgUnpack(self, args):
  1508.         for i in range(len(args)):
  1509.             arg = args[i]
  1510.             if isinstance(arg, tuple):
  1511.                 self.emit('LOAD_FAST', '.%d' % i * 2)
  1512.                 self.unpackSequence(arg)
  1513.                 continue
  1514.         
  1515.  
  1516.     
  1517.     def unpackSequence(self, tup):
  1518.         if VERSION > 1:
  1519.             self.emit('UNPACK_SEQUENCE', len(tup))
  1520.         else:
  1521.             self.emit('UNPACK_TUPLE', len(tup))
  1522.         for elt in tup:
  1523.             if isinstance(elt, tuple):
  1524.                 self.unpackSequence(elt)
  1525.                 continue
  1526.             self._nameOp('STORE', elt)
  1527.         
  1528.  
  1529.     unpackTuple = unpackSequence
  1530.  
  1531.  
  1532. class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode, CodeGenerator):
  1533.     super_init = CodeGenerator.__init__
  1534.     scopes = None
  1535.     __super_init = AbstractFunctionCode.__init__
  1536.     
  1537.     def __init__(self, func, scopes, isLambda, class_name, mod):
  1538.         self.scopes = scopes
  1539.         self.scope = scopes[func]
  1540.         self._FunctionCodeGenerator__super_init(func, scopes, isLambda, class_name, mod)
  1541.         self.graph.setFreeVars(self.scope.get_free_vars())
  1542.         self.graph.setCellVars(self.scope.get_cell_vars())
  1543.         if self.scope.generator is not None:
  1544.             self.graph.setFlag(CO_GENERATOR)
  1545.         
  1546.  
  1547.  
  1548.  
  1549. class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode, CodeGenerator):
  1550.     super_init = CodeGenerator.__init__
  1551.     scopes = None
  1552.     __super_init = AbstractFunctionCode.__init__
  1553.     
  1554.     def __init__(self, gexp, scopes, class_name, mod):
  1555.         self.scopes = scopes
  1556.         self.scope = scopes[gexp]
  1557.         self._GenExprCodeGenerator__super_init(gexp, scopes, 1, class_name, mod)
  1558.         self.graph.setFreeVars(self.scope.get_free_vars())
  1559.         self.graph.setCellVars(self.scope.get_cell_vars())
  1560.         self.graph.setFlag(CO_GENERATOR)
  1561.  
  1562.  
  1563.  
  1564. class AbstractClassCode:
  1565.     
  1566.     def __init__(self, klass, scopes, module):
  1567.         self.class_name = klass.name
  1568.         self.module = module
  1569.         self.graph = pyassem.PyFlowGraph(klass.name, klass.filename, optimized = 0, klass = 1)
  1570.         self.super_init()
  1571.         lnf = walk(klass.code, self.NameFinder(), verbose = 0)
  1572.         self.locals.push(lnf.getLocals())
  1573.         self.graph.setFlag(CO_NEWLOCALS)
  1574.         if klass.doc:
  1575.             self.setDocstring(klass.doc)
  1576.         
  1577.  
  1578.     
  1579.     def get_module(self):
  1580.         return self.module
  1581.  
  1582.     
  1583.     def finish(self):
  1584.         self.graph.startExitBlock()
  1585.         self.emit('LOAD_LOCALS')
  1586.         self.emit('RETURN_VALUE')
  1587.  
  1588.  
  1589.  
  1590. class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
  1591.     super_init = CodeGenerator.__init__
  1592.     scopes = None
  1593.     __super_init = AbstractClassCode.__init__
  1594.     
  1595.     def __init__(self, klass, scopes, module):
  1596.         self.scopes = scopes
  1597.         self.scope = scopes[klass]
  1598.         self._ClassCodeGenerator__super_init(klass, scopes, module)
  1599.         self.graph.setFreeVars(self.scope.get_free_vars())
  1600.         self.graph.setCellVars(self.scope.get_cell_vars())
  1601.         self.set_lineno(klass)
  1602.         self.emit('LOAD_GLOBAL', '__name__')
  1603.         self.storeName('__module__')
  1604.         if klass.doc:
  1605.             self.emit('LOAD_CONST', klass.doc)
  1606.             self.storeName('__doc__')
  1607.         
  1608.  
  1609.  
  1610.  
  1611. def generateArgList(arglist):
  1612.     '''Generate an arg list marking TupleArgs'''
  1613.     args = []
  1614.     extra = []
  1615.     count = 0
  1616.     for i in range(len(arglist)):
  1617.         elt = arglist[i]
  1618.         if isinstance(elt, str):
  1619.             args.append(elt)
  1620.             continue
  1621.         if isinstance(elt, tuple):
  1622.             args.append(TupleArg(i * 2, elt))
  1623.             extra.extend(misc.flatten(elt))
  1624.             count = count + 1
  1625.             continue
  1626.         raise ValueError, 'unexpect argument type:', elt
  1627.     
  1628.     return (args + extra, count)
  1629.  
  1630.  
  1631. def findOp(node):
  1632.     '''Find the op (DELETE, LOAD, STORE) in an AssTuple tree'''
  1633.     v = OpFinder()
  1634.     walk(node, v, verbose = 0)
  1635.     return v.op
  1636.  
  1637.  
  1638. class OpFinder:
  1639.     
  1640.     def __init__(self):
  1641.         self.op = None
  1642.  
  1643.     
  1644.     def visitAssName(self, node):
  1645.         if self.op is None:
  1646.             self.op = node.flags
  1647.         elif self.op != node.flags:
  1648.             raise ValueError, 'mixed ops in stmt'
  1649.         
  1650.  
  1651.     visitAssAttr = visitAssName
  1652.     visitSubscript = visitAssName
  1653.  
  1654.  
  1655. class Delegator:
  1656.     '''Base class to support delegation for augmented assignment nodes
  1657.  
  1658.     To generator code for augmented assignments, we use the following
  1659.     wrapper classes.  In visitAugAssign, the left-hand expression node
  1660.     is visited twice.  The first time the visit uses the normal method
  1661.     for that node .  The second time the visit uses a different method
  1662.     that generates the appropriate code to perform the assignment.
  1663.     These delegator classes wrap the original AST nodes in order to
  1664.     support the variant visit methods.
  1665.     '''
  1666.     
  1667.     def __init__(self, obj):
  1668.         self.obj = obj
  1669.  
  1670.     
  1671.     def __getattr__(self, attr):
  1672.         return getattr(self.obj, attr)
  1673.  
  1674.  
  1675.  
  1676. class AugGetattr(Delegator):
  1677.     pass
  1678.  
  1679.  
  1680. class AugName(Delegator):
  1681.     pass
  1682.  
  1683.  
  1684. class AugSlice(Delegator):
  1685.     pass
  1686.  
  1687.  
  1688. class AugSubscript(Delegator):
  1689.     pass
  1690.  
  1691. wrapper = {
  1692.     ast.Getattr: AugGetattr,
  1693.     ast.Name: AugName,
  1694.     ast.Slice: AugSlice,
  1695.     ast.Subscript: AugSubscript }
  1696.  
  1697. def wrap_aug(node):
  1698.     return wrapper[node.__class__](node)
  1699.  
  1700. if __name__ == '__main__':
  1701.     for file in sys.argv[1:]:
  1702.         compileFile(file)
  1703.     
  1704.  
  1705.